﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TangoGames.Base;
using TangoGames.Scene;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace incubation_xna3d.Enemies

{
    class Enemie : GameObject3D, IEnemie
    {

        #region Fields

        /// <summary>
        /// Posição no tabuleiro
        /// </summary>
        Point boardPosition;

        /// <summary>
        /// Gerenciador da cena corrente
        /// </summary>
        ISceneManager sceneManager;

        /// <summary>
        /// Pontos de movimento do Soldado
        /// </summary>
        public int movementPoints = 3;

        #endregion

        #region Properties

        /// <summary>
        /// Posição no tabuleiro
        /// </summary>
        public Point BoardPosition { get { return boardPosition; } set { boardPosition = value; } }

        /// <summary>
        /// Caixa de colisão
        /// </summary>
        public BoundingBox CollisionBox { get { return ModelBoundingBox; } }

        /// <summary>
        /// Gerenciador da cena corrente
        /// </summary>
        public ISceneManager SceneManager { get { return sceneManager; } set { sceneManager = value; } }

        #endregion

        #region Constructor

        public Enemie(Game game, ICamera camera)
            : base(game, camera, game.Content.Load<Model>("Models/Enemies/dino videogame"))
        {
            this.Scale = 20.0f;
            this.Position = new Vector3(0, 8.0f, 0);
            UpdateWorld();
        }


        
        #endregion

        #region Interface Caracter

        /// <summary>
        /// Atualiza posição do tabuleiro para posição real
        /// </summary>
        /// <param name="pathMap"></param>
        public void UpdateBoardPosition(IPathMap pathMap)
        {
            Point ini = pathMap.ReversePoint(new Vector2(Position.X, Position.Z));
            Vector2 inireal = pathMap.ConvertPoint(ini);
            boardPosition = ini;
        }

        /// <summary>
        /// centraliza posição no quadrado do tabuleiro
        /// </summary>
        /// <param name="pathMap"></param>
        public void CenterPositionBoardSquare(IPathMap pathMap)
        {
            Vector2 centerPoint = pathMap.ConvertPoint(boardPosition);
            this.Position = new Vector3(centerPoint.X, this.Position.Y, centerPoint.Y);
        }

        public bool Playing { get { return false; } }

        public int MovementPoints { get { return movementPoints; } set { movementPoints = value; } }

        public int CurrentMovementPoints { get; set; }
        public int Health { get; set; }
        public int AttackPower { get; set; }

        public void Stop()
        {  }

        public void Play()
        {  }

        public bool Selected(Ray ray)
        {
            return false;
        }

        public bool isVisible(ICharacter other)
        {
            bool result = true;

            Vector3 olho = this.Position + new Vector3(0, this.modelBoundingBox.Max.Y / 2, 0);
            Vector3 olhoInimigo = (other.CollisionBox.Max + other.CollisionBox.Min) / 2;

            // Create a ray from the near clip plane to the far clip plane.
            Vector3 direction = olhoInimigo - olho;
            float distanciaInimigo = direction.Length();

            direction.Normalize();

            Ray ray = new Ray(olho, direction);

            foreach (GameObject3D obj in sceneManager.Stage.StageModels.Values)
            {
                Nullable<float> distance = ray.Intersects(obj.ModelBoundingBox);
                if (distance <= distanciaInimigo)
                {
                    result = false;
                    break;
                }
            }
            return result;
        }

        /// <summary>
        /// Mover para um ponto destino
        /// </summary>
        /// <param name="destination"></param>
        public void MoveTo(Vector3 destination)
        {
            Vector3 direction = destination - this.Position;
            direction.Normalize();
            //walkdirection = new Vector3(direction.X, 0, direction.Z);
            //this.destination = new Vector3(destination.X, Position.Y, destination.Z);
            //this.RotationY = (float)Math.Atan2((float)direction.X, (float)direction.Z);
            //Walk();

        }

        /// <summary>
        /// Mover para um ponto destino
        /// </summary>
        /// <param name="destination"></param>
        public void MoveTo(IPathMap pathmap, Point destination)
        {
            Vector2 dest = pathmap.ConvertPoint(destination);

            Vector3 positionDest = new Vector3(dest.X, Position.Y, dest.Y);

            MoveTo(positionDest);
        }


        /// <summary>
        /// Esta inativos
        /// </summary>
        public bool IsIdle { get { return true; } }

        /// <summary>
        /// Esta morto
        /// </summary>
        public bool IsDead { get { return false; } }

        public bool InRangeOfAttack(IPathMap pathMap, ICharacter character) 
        {
            return false;
        }

        public void Attack(IPathMap pathMap, ICharacter character)
        { 
        }

        public void TakenDamage(int damage) 
        { 
        }

        /// <summary>
        /// Define quem será o alvo
        /// </summary>
        /// <returns></returns>
        public ICharacter HowIsTarget(List<ICharacter> listOfCharacters)
        { 
           return listOfCharacters[0];
        }

        /// <summary>
        /// Remove objeto
        /// </summary>
        public void SelfRemove()
        {
            this.Dispose(true);
        }

        #endregion



        #region Update
        #endregion

        #region Draw
        #endregion

   }

}
